package model

import (
	"github.com/astaxie/beego"
	"github.com/astaxie/beego/orm"
	"github.com/astaxie/beego/validation"
	"mime/multipart"
	"nspel/entity"
	"nspel/util"
	"time"
)

type PostSchoolsImport struct {
	ImportFile multipart.File
}

func (postSchoolsImport *PostSchoolsImport) Validate(c *beego.Controller) error {
	file, fileHeader, err := c.GetFile("import")
	if err != nil {
		return err
	}
	if !util.ValidateFileType(fileHeader, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") {
		return err
	}
	postSchoolsImport.ImportFile = file
	return nil
}

type GetSchoolListAdministrator struct {
	ProvinceId  int64
	CityId      int64
	AreaId      int64
	SchoolName  string
	JoinYear    int64
	PageSize    int64
	CurrentPage int64
}

func (getSchoolListAdministrator *GetSchoolListAdministrator) Validate(provinceId string, cityId string, areaId string, schoolName string, joinYear string, pageSize string, currentPage string, c *beego.Controller) bool {
	var err error
	getSchoolListAdministrator.ProvinceId, err = c.GetInt64(provinceId)
	if err != nil {
		return false
	}
	getSchoolListAdministrator.CityId, err = c.GetInt64(cityId)
	if err != nil {
		return false
	}
	getSchoolListAdministrator.AreaId, err = c.GetInt64(areaId)
	if err != nil {
		return false
	}
	getSchoolListAdministrator.SchoolName = c.GetString(schoolName)
	getSchoolListAdministrator.JoinYear, err = c.GetInt64(joinYear)
	if err != nil {
		return false
	}
	getSchoolListAdministrator.PageSize, err = c.GetInt64(pageSize)
	if err != nil {
		return false
	}
	getSchoolListAdministrator.CurrentPage, err = c.GetInt64(currentPage)
	if err != nil {
		return false
	}
	return true
}

type GetSchoolListArea struct {
	JoinYear    int64
	SchoolId    int64
	PageSize    int64
	CurrentPage int64
}

func (getSchoolListArea *GetSchoolListArea) Validate(joinYear string, schoolId string, pageSize string, currentPage string, c *beego.Controller, uid int64) (bool, error) {
	var err error
	getSchoolListArea.JoinYear, err = c.GetInt64(joinYear)
	if err != nil {
		return false, nil
	}
	getSchoolListArea.SchoolId, err = c.GetInt64(schoolId)
	if err != nil {
		return false, nil
	}
	getSchoolListArea.PageSize, err = c.GetInt64(pageSize)
	if err != nil {
		return false, nil
	}
	getSchoolListArea.CurrentPage, err = c.GetInt64(currentPage)
	if err != nil {
		return false, nil
	}
	if getSchoolListArea.SchoolId != 0 {
		school := new(entity.School)
		err = school.SelectAllById(getSchoolListArea.SchoolId)
		if err != nil {
			return false, err
		}
		area := new(entity.Area)
		err = area.SelectAllById(school.ExperimentAreaId)
		if err != nil {
			return false, err
		}
		if area.UserId.Int64 != int64(uid) {
			return false, nil
		}
	}
	return true, nil
}

type PostSchoolCodeValidateExist struct {
	Id         int64  `json:"id"`
	SchoolCode string `json:"schoolCode"`
}

func (postSchoolCodeValidateExist *PostSchoolCodeValidateExist) Validate(uid int64, authority byte) (bool, error) {
	if len(postSchoolCodeValidateExist.SchoolCode) == 0 {
		return false, nil
	}
	if postSchoolCodeValidateExist.Id > 0 {
		school := new(entity.School)
		err := school.SelectAllById(postSchoolCodeValidateExist.Id)
		if err != nil {
			return false, err
		}
		if authority == entity.ManagerAuthority.Area {
			area := new(entity.Area)
			err = area.SelectAllByUserId(uid)
			if err != nil {
				return false, err
			}
			if school.ExperimentAreaId != area.Id {
				return false, nil
			}
		}
	}
	return true, nil
}

type PostSchoolModify struct {
	Id               int64     `json:"id"`
	Name             string    `json:"name" valid:"MinSize(1);MaxSize(20)"`
	IsStandout       bool      `json:"isStandout"`
	SchoolType       string    `json:"schoolType" valid:"Match(/^(小学)|(初中)|(高中)$/)"`
	Headmaster       string    `json:"headmaster" valid:"MaxSize(10)"`
	HeadmasterPhone  string    `json:"headmasterPhone"`
	HeadmasterEmail  string    `json:"headmasterEmail"`
	Contact          string    `json:"contact" valid:"MaxSize(10)"`
	ContactPhone     string    `json:"contactPhone"`
	ContactEmail     string    `json:"contactEmail"`
	JoinAt           time.Time `json:"joinAt"`
	StudentNum       int64     `json:"studentNum" valid:"Min(0)"`
	SchoolCode       string    `json:"schoolCode" valid:"MinSize(1);MaxSize(50)"`
	Code             string    `json:"code" valid:"MaxSize(20)"`
	HasApply         bool      `json:"hasApply"`
	Homepage         string    `json:"homepage" valid:"MaxSize(50)"`
	OfficialAccounts string    `json:"officialAccounts" valid:"MaxSize(50)"`
	IsExperiment     bool      `json:"isExperiment"`
	ExperimentAt     time.Time `json:"experimentAt"`
	StandoutAt       time.Time `json:"standoutAt"`
	ContactAddress   string    `json:"contactAddress" valid:"MaxSize(255)"`
}

func (postSchoolModify *PostSchoolModify) Validate(uid int64, authority byte) (bool, error) {
	valid := validation.Validation{}
	b, err := valid.Valid(postSchoolModify)
	if err != nil || !b {
		return b, err
	}
	if len(postSchoolModify.HeadmasterPhone) > 0 {
		valid.Phone(postSchoolModify.HeadmasterPhone, "headmasterPhone")
		if valid.HasErrors() {
			return false, nil
		}
	}
	if len(postSchoolModify.HeadmasterEmail) > 0 {
		valid.Email(postSchoolModify.HeadmasterEmail, "headmasterEmail")
		if valid.HasErrors() {
			return false, nil
		}
	}
	if len(postSchoolModify.ContactEmail) > 0 {
		valid.Email(postSchoolModify.ContactEmail, "contactEmail")
		if valid.HasErrors() {
			return false, nil
		}
	}
	{
		school := new(entity.School)
		err = school.SelectAllBySchoolCode(postSchoolModify.SchoolCode)
		if err != nil && err != orm.ErrNoRows {
			return false, err
		} else if err == nil && school.Id != postSchoolModify.Id {
			return false, nil
		}
	}
	school := new(entity.School)
	err = school.SelectAllById(postSchoolModify.Id)
	if err != nil {
		return false, err
	}
	if len(postSchoolModify.ContactPhone) > 0 {
		valid.Phone(postSchoolModify.ContactPhone, "contactPhone")
		if valid.HasErrors() {
			return false, nil
		}
		if !school.UserId.Valid {
			manager := new(entity.Manager)
			err = manager.SelectAllByUserName(postSchoolModify.ContactPhone)
			if err != nil && err != orm.ErrNoRows {
				return false, err
			} else if err == nil && manager.Id != int64(school.UserId.Int64) {
				return false, nil
			}
		}
	}
	if authority == entity.ManagerAuthority.Area {
		area := new(entity.Area)
		err = area.SelectAllByUserId(uid)
		if err != nil {
			return false, err
		}
		if school.ExperimentAreaId != area.Id {
			return false, nil
		}
	}
	return true, nil
}

type PostSchoolAdd struct {
	CountryId        int64     `json:"-"`
	ProvinceId       int64     `json:"provinceId"`
	CityId           int64     `json:"cityId"`
	AreaId           int64     `json:"areaId"`
	ExperimentAreaId int64     `json:"experimentAreaId"`
	Name             string    `json:"name" valid:"MinSize(1);MaxSize(20)"`
	IsStandout       bool      `json:"isStandout"`
	SchoolType       string    `json:"schoolType" valid:"Match(/^(小学)|(初中)|(高中)$/)"`
	Headmaster       string    `json:"headmaster" valid:"MaxSize(10)"`
	HeadmasterPhone  string    `json:"headmasterPhone"`
	HeadmasterEmail  string    `json:"headmasterEmail"`
	Contact          string    `json:"contact" valid:"MaxSize(10)"`
	ContactPhone     string    `json:"contactPhone"`
	ContactEmail     string    `json:"contactEmail"`
	JoinAt           time.Time `json:"joinAt"`
	StudentNum       int64     `json:"studentNum" valid:"Min(0)"`
	SchoolCode       string    `json:"schoolCode" valid:"MinSize(1);MaxSize(50)"`
	Code             string    `json:"code" valid:"MaxSize(20)"`
	HasApply         bool      `json:"hasApply"`
	Homepage         string    `json:"homepage" valid:"MaxSize(50)"`
	OfficialAccounts string    `json:"officialAccounts" valid:"MaxSize(50)"`
	IsExperiment     bool      `json:"isExperiment"`
	ExperimentAt     time.Time `json:"experimentAt"`
	StandoutAt       time.Time `json:"standoutAt"`
	ContactAddress   string    `json:"contactAddress" valid:"MaxSize(255)"`
}

func (postSchoolAdd *PostSchoolAdd) Validate(uid int64, authority byte) (bool, error) {
	valid := validation.Validation{}
	b, err := valid.Valid(postSchoolAdd)
	if err != nil || !b {
		return b, err
	}
	if authority == entity.ManagerAuthority.Area {
		area := new(entity.Area)
		err := area.SelectAllByUserId(uid)
		if err != nil {
			return false, err
		}
		postSchoolAdd.CountryId = area.CountryId
		postSchoolAdd.ProvinceId = area.ProvinceId
		postSchoolAdd.CityId = area.CityId
		postSchoolAdd.ExperimentAreaId = area.Id
	} else if authority == entity.ManagerAuthority.Administrator {
		area := new(entity.Area)
		err := area.SelectAllById(postSchoolAdd.AreaId)
		if err != nil {
			return false, err
		}
		if area.CityId != postSchoolAdd.CityId || area.ProvinceId != postSchoolAdd.ProvinceId {
			return false, nil
		}
		err = area.SelectAllById(postSchoolAdd.ExperimentAreaId)
		if err != nil {
			return false, err
		}
		if area.CityId != postSchoolAdd.CityId || area.ProvinceId != postSchoolAdd.ProvinceId {
			return false, nil
		}
		postSchoolAdd.CountryId = area.CountryId
	}
	if len(postSchoolAdd.HeadmasterPhone) > 0 {
		valid.Phone(postSchoolAdd.HeadmasterPhone, "headmasterPhone")
		if valid.HasErrors() {
			return false, nil
		}
	}
	if len(postSchoolAdd.HeadmasterEmail) > 0 {
		valid.Email(postSchoolAdd.HeadmasterEmail, "headmasterEmail")
		if valid.HasErrors() {
			return false, nil
		}
	}
	if len(postSchoolAdd.ContactPhone) > 0 {
		valid.Phone(postSchoolAdd.ContactPhone, "contactPhone")
		if valid.HasErrors() {
			return false, nil
		}
		manager := new(entity.Manager)
		err := manager.SelectAllByUserName(postSchoolAdd.ContactPhone)
		if err != nil && err != orm.ErrNoRows {
			return false, err
		} else if err == nil {
			return false, nil
		}
	}
	if len(postSchoolAdd.ContactEmail) > 0 {
		valid.Email(postSchoolAdd.ContactEmail, "contactEmail")
		if valid.HasErrors() {
			return false, nil
		}
	}
	school := new(entity.School)
	err = school.SelectAllBySchoolCode(postSchoolAdd.SchoolCode)
	if err != nil && err != orm.ErrNoRows {
		return false, err
	} else if err == nil {
		return false, nil
	}
	return true, nil
}

type DeleteSchool struct {
	Id []int64 `json:"id"`
}

type GetSchoolExportAdministratorReq struct {
	ProvinceId int64
	CityId     int64
	AreaId     int64
	SchoolName string
	JoinYear   int64
}

func (getSchoolExportAdministratorReq *GetSchoolExportAdministratorReq) Validate(provinceId string, cityId string, areaId string, schoolName string, joinYear string, c *beego.Controller) bool {
	var err error
	getSchoolExportAdministratorReq.ProvinceId, err = c.GetInt64(provinceId)
	if err != nil {
		return false
	}
	getSchoolExportAdministratorReq.CityId, err = c.GetInt64(cityId)
	if err != nil {
		return false
	}
	getSchoolExportAdministratorReq.AreaId, err = c.GetInt64(areaId)
	if err != nil {
		return false
	}
	getSchoolExportAdministratorReq.SchoolName = c.GetString(schoolName)
	getSchoolExportAdministratorReq.JoinYear, err = c.GetInt64(joinYear)
	if err != nil {
		return false
	}
	return true
}

type GetSchoolExportAreaReq struct {
	JoinYear int64
	SchoolId int64
}

func (getSchoolExportAreaReq *GetSchoolExportAreaReq) Validate(joinYear string, schoolId string, c *beego.Controller, uid int64) (bool, error) {
	var err error
	getSchoolExportAreaReq.JoinYear, err = c.GetInt64(joinYear)
	if err != nil {
		return false, nil
	}
	getSchoolExportAreaReq.SchoolId, err = c.GetInt64(schoolId)
	if err != nil {
		return false, nil
	}
	if getSchoolExportAreaReq.SchoolId != 0 {
		school := new(entity.School)
		err = school.SelectAllById(getSchoolExportAreaReq.SchoolId)
		if err != nil {
			return false, err
		}
		area := new(entity.Area)
		err = area.SelectAllById(school.ExperimentAreaId)
		if err != nil {
			return false, err
		}
		if area.UserId.Int64 != int64(uid) {
			return false, nil
		}
	}
	return true, nil
}
